package org.jplcc.memory;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.WeakHashMap;
import java.util.logging.Logger;

import org.jplcc.Connection;
import org.jplcc.Driver;
import org.jplcc.DriverManager;
import org.jplcc.JPLCCException;

/**
 * @author csavard
 * 
 */
public class MemoryPlcDriver implements Driver {

	private static Logger logger = Logger.getLogger("jplcc.xml");

	private Map<String, WeakReference<MemoryMap>> plcNameToMemoryMap;

	static {
		try {
			DriverManager.registerDriver(new MemoryPlcDriver());
		} catch (JPLCCException e) {
			logger.warning(e.getMessage());
		}
	}

	private MemoryPlcDriver() {
		super();
		plcNameToMemoryMap = new WeakHashMap<String, WeakReference<MemoryMap>>();
	}

	@Override
	public boolean acceptsURL(String url) throws JPLCCException {
		return parseURL(url) != null;
	}

	@Override
	public Connection connect(String url) throws JPLCCException {
		MemoryConnection connection = null;

		String plcName = parseURL(url);
		if (plcName != null) {
			WeakReference<MemoryMap> memoryMap = plcNameToMemoryMap.get(plcName);
			if (memoryMap == null || memoryMap.get() == null) {
				memoryMap = new WeakReference<MemoryMap>(new MemoryMap(plcName));
				plcNameToMemoryMap.put(plcName, memoryMap);
			}
			connection = new MemoryConnection(memoryMap.get());
		}

		return connection;
	}

	private String parseURL(String url) {
		String plcName = null;

		StringTokenizer stringTokenizer = new StringTokenizer(url, ":");
		if (stringTokenizer.countTokens() > 0) {

			String jplccToken = stringTokenizer.nextToken();
			if (jplccToken.equalsIgnoreCase("jplcc")
					&& stringTokenizer.hasMoreElements()) {

				String driverName = stringTokenizer.nextToken();
				if (driverName.equalsIgnoreCase("memoryplc")
						&& stringTokenizer.hasMoreElements()) {
					plcName = stringTokenizer.nextToken();
				}
			}
		}
		return plcName;
	}

	@Override
	public int getMajorVersion() {
		return 1;
	}

	@Override
	public int getMinorVersion() {
		return 0;
	}

}
